package com.tansun.tandata.service.impl;

import java.io.ByteArrayOutputStream;
import java.io.PrintStream;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import com.tansun.tandata.entity.LogInfoErro;
import com.tansun.tandata.service.LdapService;
import com.tansun.tandata.utils.*;
import com.tansun.tandata.vo.LdapUser;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.google.common.collect.Lists;
import com.tansun.tandata.feign.SysFeignService;
import com.tansun.tandata.vo.res.RoleInfoByRoleCodesVO;
import com.tansun.tandata.vo.res.UserRoleByLoginNameVO;
import com.tansun.tjmas.cloud.base.auth.common.SystemConstant;
import com.tansun.tjmas.cloud.base.auth.entity.CheckUserResultDTO;
import com.tansun.tjmas.cloud.base.auth.entity.LogoutFOResultDTO;
import com.tansun.tjmas.cloud.base.auth.entity.RoleApiRelationDTO;
import com.tansun.tjmas.cloud.base.auth.service.CustomizeService;
import com.tansun.tjmas.cloud.base.redis.utils.RedisUtils;

@Service
public class CustomizeServiceImpl  implements CustomizeService {

	@Autowired
	private SysFeignService sysFeignService;
	@Autowired
	private RedisUtils redisUtils;
	@Autowired
	private LocaleMessage localeMessage;
	@Autowired
	private LdapService ldapService;
	@Value("${spring.profiles.active}")
	private String active;

	/**
	 * 自定义账号密码校验接口,接口地址：/external/checkUserAuth
	 * 设置返回结果
	 * 包括：1.设置返回状态码，0成功1失败，分别在SystemConstant
	 *       2.设置返回信息 msg
	 *       3.设置version，用于灰度，version需自行实现后塞进CheckUserResultDTO
	 *       4.设置roles，即该用户属于哪些角色
	 *       5.设置extra_data额外数据，即需要传递至下游应用的数据
	 */
	@Override
	public CheckUserResultDTO checkPassword(String username, String password) {
		//创建需要传递至下游应用的数据
		Map<String, Object> extra_data = new HashMap<String, Object>();
		try {
			if (!"dev".equals(active)) {
				//非开发环境下验证LDAP域账号
				LdapUser ldapUser = ldapService.ldapAuth(username, password);
				if (ldapUser == null) {
					//域账号校验没过如果系统中存在此域账号则删除此域账号
					sysFeignService.lockLdapUserByLoginName(username);
				} else {
					ldapUser.setPassword(MD5Util.MD5(password).toLowerCase());
					// 同步提数系统账号
					System.out.println("zhun bei tong bu yu zhanghao************"+ldapUser.getSAMAccountName());
					sysFeignService.ldapUserToSysUser(ldapUser);
					System.out.println("tong bu wan cheng ************"+ldapUser.getSAMAccountName());
				}
			}
			//对密码进行加密
			password = MD5Util.MD5(password).toLowerCase();
			//查询用户信息
			ResponseBase responseBase = sysFeignService.getUserAndRoleInfoByLoginName(username);
			if (responseBase.getCode().equals(Constants.HTTP_RES_CODE_200)) {
				//获取对应字符串
				String resultData = String.valueOf(responseBase.getData());
				UserRoleByLoginNameVO uvo = JSONObject.parseObject(resultData, UserRoleByLoginNameVO.class);
				if (uvo != null
						&& uvo.getUserInfo().getUserCode() != null
						&& !uvo.getUserInfo().getUserCode().equals(Constants.CHAR_BLANK)
						&& uvo.getUserInfo().getPassword().equals(password)) {//密码无误
					if (uvo.getUserInfo().getStatus() != null
							&& !uvo.getUserInfo().getStatus().equals(Constants.CHAR_BLANK)
							&& !uvo.getUserInfo().getStatus().equals(Constants.USER_STATUS_FREEZE)) {
						//设置用户业务人员权限活着审核人员权限
						//TODO
						//设置用户信息
						extra_data = JSON.parseObject(responseBase.getData().toString());
						//设置机构信息
						ResponseBase orgResponseBase = sysFeignService.getChildOrgByOrgCode(uvo.getUserInfo().getOrgCode());
						if (orgResponseBase.getCode() == Constants.HTTP_RES_CODE_200) {
							redisUtils.set(Constants.CHILD_ORG_REDIS + uvo.getUserInfo().getUserCode(), JSON.parseObject(orgResponseBase.getData().toString()));
						}
						//返回成功
						CheckUserResultDTO checkUserResult = new CheckUserResultDTO(SystemConstant.OPERATION_SUCCESS, "success!", "", uvo.getRole(), extra_data);
						return checkUserResult;
					} else {
						//用户被冻结
						CheckUserResultDTO checkUserResult = new CheckUserResultDTO(SystemConstant.OPERATION_FAILED, localeMessage.getMessage("auth.message.user.status"), "", "", extra_data);
						return checkUserResult;
					}
				} else {
					//密码校验失败
					CheckUserResultDTO checkUserResult = new CheckUserResultDTO(SystemConstant.OPERATION_FAILED, "密码校验失败!", "", "", extra_data);
					return checkUserResult;
				}
			} else {
				//密码校验失败
				CheckUserResultDTO checkUserResult = new CheckUserResultDTO(SystemConstant.OPERATION_FAILED, "调用获取用户信息接口没有成功返回!错误码:"+responseBase.getCode(), "", "", extra_data);
				return checkUserResult;
			}
		}catch (Exception e){
			e.printStackTrace();
			ByteArrayOutputStream baos = new ByteArrayOutputStream();
			e.printStackTrace(new PrintStream(baos));
			//保存错误日志
			LogInfoErro log = new LogInfoErro();
			log.setServerId("tandata-auth");//tandata-auth
			log.setUrl(log.getServerId()+"/external/checkUserAuth");
			log.setParamStr("username:"+username+"password:"+password);
			log.setReqType(1);//post
			log.setDesribe(baos.toString());
			sysFeignService.insertLogInfoErro(log);
			//密码校验失败
			CheckUserResultDTO checkUserResult = new CheckUserResultDTO(SystemConstant.OPERATION_FAILED, e.getMessage(), "", "", extra_data);
			return checkUserResult;
		}
	}

	/**
	 * 	自定义角色与api关系接口,接口地址：/external/updateRoleApiRelation
	 */
	@Override
	public List<RoleApiRelationDTO> getAllRoleApiRelation() {
		//查询
		ResponseBase responseBase = sysFeignService.getRoleAndApis();
		List<RoleApiRelationDTO> list = Lists.newArrayList();
		if(responseBase.getCode().equals(Constants.HTTP_RES_CODE_200)) {
			String resultData = String.valueOf(responseBase.getData());
			List<RoleInfoByRoleCodesVO> rvoList = JSONArray.parseArray(resultData, RoleInfoByRoleCodesVO.class);
			for (RoleInfoByRoleCodesVO rvo : rvoList) {
				RoleApiRelationDTO roleApiRelationDTO = null;
				for (String api : rvo.getApis()) {
					roleApiRelationDTO = new RoleApiRelationDTO(rvo.getRoleCode(),api);
					list.add(roleApiRelationDTO);
				}
			}
		}

		return list;
	}

	/**
	 * 自定义退出登录删除用户数据，接口地址：/external/logout
	 */
	@Override
	public LogoutFOResultDTO logoutFollowOperation(String username, String redisId) {
		//执行登出操作的额外动作，这里依据项目组需求自行实现
		//redisUtils.delete(redisId);
		return new LogoutFOResultDTO(SystemConstant.OPERATION_SUCCESS, "success!");
	}
}

